package Limit.BuffDoll;

import static l1j.server.server.model.skill.L1SkillId.BLOODLUST;
import static l1j.server.server.model.skill.L1SkillId.BURNING_WEAPON;
import static l1j.server.server.model.skill.L1SkillId.DRESS_DEXTERITY;
import static l1j.server.server.model.skill.L1SkillId.DRESS_MIGHTY;
import static l1j.server.server.model.skill.L1SkillId.EARTH_BLESS;
import static l1j.server.server.model.skill.L1SkillId.EARTH_SKIN;
import static l1j.server.server.model.skill.L1SkillId.EFFECT_BLESS_OF_MAZU;
import static l1j.server.server.model.skill.L1SkillId.ENTANGLE;
import static l1j.server.server.model.skill.L1SkillId.FIRE_BLESS;
import static l1j.server.server.model.skill.L1SkillId.FIRE_WEAPON;
import static l1j.server.server.model.skill.L1SkillId.GLOWING_AURA;
import static l1j.server.server.model.skill.L1SkillId.GREATER_HASTE;
import static l1j.server.server.model.skill.L1SkillId.HASTE;
import static l1j.server.server.model.skill.L1SkillId.HOLY_WALK;
import static l1j.server.server.model.skill.L1SkillId.IRON_SKIN;
import static l1j.server.server.model.skill.L1SkillId.MASS_SLOW;
import static l1j.server.server.model.skill.L1SkillId.MOVING_ACCELERATION;
import static l1j.server.server.model.skill.L1SkillId.PHYSICAL_ENCHANT_DEX;
import static l1j.server.server.model.skill.L1SkillId.PHYSICAL_ENCHANT_STR;
import static l1j.server.server.model.skill.L1SkillId.SHADOW_ARMOR;
import static l1j.server.server.model.skill.L1SkillId.SHIELD;
import static l1j.server.server.model.skill.L1SkillId.SHINING_AURA;
import static l1j.server.server.model.skill.L1SkillId.SLOW;
import static l1j.server.server.model.skill.L1SkillId.STATUS_BRAVE;
import static l1j.server.server.model.skill.L1SkillId.STATUS_BRAVE2;
import static l1j.server.server.model.skill.L1SkillId.STATUS_ELFBRAVE;
import static l1j.server.server.model.skill.L1SkillId.STATUS_HASTE;
import static l1j.server.server.model.skill.L1SkillId.STORM_EYE;
import static l1j.server.server.model.skill.L1SkillId.STORM_SHOT;
import static l1j.server.server.model.skill.L1SkillId.WIND_SHOT;
import static l1j.server.server.model.skill.L1SkillId.WIND_WALK;
import l1j.server.server.model.Instance.L1PcInstance;
import l1j.server.server.serverpackets.S_Dexup;
import l1j.server.server.serverpackets.S_HPUpdate;
import l1j.server.server.serverpackets.S_MPUpdate;
import l1j.server.server.serverpackets.S_NPCTalkReturn;
import l1j.server.server.serverpackets.S_OwnCharAttrDef;
import l1j.server.server.serverpackets.S_OwnCharStatus;
import l1j.server.server.serverpackets.S_PacketBox;
import l1j.server.server.serverpackets.S_SPMR;
import l1j.server.server.serverpackets.S_ServerMessage;
import l1j.server.server.serverpackets.S_SkillBrave;
import l1j.server.server.serverpackets.S_SkillHaste;
import l1j.server.server.serverpackets.S_SkillIconAura;
import l1j.server.server.serverpackets.S_SkillIconShield;
import l1j.server.server.serverpackets.S_SkillSound;
import l1j.server.server.serverpackets.S_Strup;
import l1j.server.server.serverpackets.S_SystemMessage;

public class BuffDoll_RunSkill{
	
	private static BuffDoll_RunSkill _instance;
	
	public static BuffDoll_RunSkill getInstance() {
		if (_instance == null) {
			_instance = new BuffDoll_RunSkill();
		}
		return _instance;
	}
	
	public void runSkill(L1PcInstance pc, int[] buffinfo, int itemid, String name, String mp, String maxMp, int getid)
	{
		boolean checkEquipped = true;
		int type = 0;
		int typeNum = 0;
		int img = buffinfo[1];
		int skillid = buffinfo[0];
		int place = buffinfo[4];
		int time = 0;
		
		deleteRepeatedSkills(pc, skillid);
		
		switch (skillid)
		{
		case 3:
			time = 1800;
			pc.addAc(-2);
			pc.sendPackets(new S_SkillIconShield(3, time));
			break;
		case 26:
			time = 1200;
			pc.addDex((byte) 5);
			pc.sendPackets(new S_Dexup(pc, 5, time));
			break;
		case 42:
			time = 1200;
			pc.addStr((byte) 5);
			pc.sendPackets(new S_Strup(pc, 5, time));
			break;
		case 48:
			time = 1200;
			pc.addDmgup(2);
			pc.addHitup(2);	
			break;
		case 52:
			time = 1200;
			if (pc.hasSkillEffect(STATUS_BRAVE)) { // 勇敢藥水 1.33倍
				pc.killSkillEffectTimer(STATUS_BRAVE);
			}
			if (pc.hasSkillEffect(STATUS_ELFBRAVE)) { // 精靈餅乾 1.15倍
				pc.killSkillEffectTimer(STATUS_ELFBRAVE);
			}
			if (pc.hasSkillEffect(HOLY_WALK)) { // 神聖疾走 移速1.33倍
				pc.killSkillEffectTimer(HOLY_WALK);
			}
			if (pc.hasSkillEffect(MOVING_ACCELERATION)) { // 行走加速 移速1.33倍
				pc.killSkillEffectTimer(MOVING_ACCELERATION);
			}
			if (pc.hasSkillEffect(WIND_WALK)) { // 風之疾走 移速1.33倍
				pc.killSkillEffectTimer(WIND_WALK);
			}
			if (pc.hasSkillEffect(BLOODLUST)) { // 血之渴望 攻速1.33倍
				pc.killSkillEffectTimer(BLOODLUST);
			}
			if (pc.hasSkillEffect(STATUS_BRAVE2)) { // 超級加速 2.66倍
				pc.killSkillEffectTimer(STATUS_BRAVE2);
			}
			pc.setBraveSpeed(4);
			pc.sendPackets(new S_SkillBrave(pc.getId(), 4, time));
			pc.broadcastPacket(new S_SkillBrave(pc.getId(), 4, 0));
			break;
		case 54:
			time = 2400;
			if (pc.hasSkillEffect(HASTE) || pc.hasSkillEffect(GREATER_HASTE)
					|| pc.hasSkillEffect(STATUS_HASTE)) {
				if (pc.hasSkillEffect(HASTE)) { // 加速術
					pc.killSkillEffectTimer(HASTE);
				} else if (pc.hasSkillEffect(GREATER_HASTE)) { // 強力加速術
					pc.killSkillEffectTimer(GREATER_HASTE);
				} else if (pc.hasSkillEffect(STATUS_HASTE)) { // 自我加速藥水
					pc.killSkillEffectTimer(STATUS_HASTE);
				}
			}
			pc.sendPackets(new S_SkillHaste(pc.getId(), 1, time));
			pc.broadcastPacket(new S_SkillHaste(pc.getId(), 1, 0));
			pc.sendPackets(new S_ServerMessage(184)); // 
			pc.setMoveSpeed(1);
			break;
		case 55:
			time = 320;
			pc.addAc(10);
			pc.addDmgup(5);
			pc.addHitup(2);
			break;
		case 79:
			time  = 1800;
			pc.setAdvenHp(pc.getBaseMaxHp() / 5);
			pc.setAdvenMp(pc.getBaseMaxMp() / 5);
			pc.addMaxHp(pc.getAdvenHp());
			pc.addMaxMp(pc.getAdvenMp());
			pc.sendPackets(new S_HPUpdate(pc.getCurrentHp(), pc.getMaxHp()));
			if (pc.isInParty()) { // パーティー中
				pc.getParty().updateMiniHP(pc);
			}
			pc.sendPackets(new S_MPUpdate(pc.getCurrentMp(), pc.getMaxMp()));
			break;
		case 88:
			time = 32;
			break;
		case 89:
			time = 64;
			break;
		case 90:
			time = 64;
			type = 2;
			typeNum = 7;
			break;
		case 91:
			time = 64;
			type = 1;
			typeNum = 3;
			break;
		case 98:
			time = 320;
				break;
		case 99:
			time = 960;
			pc.addAc(-3);
			pc.sendPackets(new S_SkillIconShield(3, time));
			break;
		case 101:
			time = 960;
			if (pc.hasSkillEffect(STATUS_BRAVE)) { // 勇敢藥水 1.33倍
				pc.killSkillEffectTimer(STATUS_BRAVE);
			}
			if (pc.hasSkillEffect(STATUS_ELFBRAVE)) { // 精靈餅乾 1.15倍
				pc.killSkillEffectTimer(STATUS_ELFBRAVE);
			}
			if (pc.hasSkillEffect(HOLY_WALK)) { // 神聖疾走 移速1.33倍
				pc.killSkillEffectTimer(HOLY_WALK);
			}
			if (pc.hasSkillEffect(MOVING_ACCELERATION)) { // 行走加速 移速1.33倍
				pc.killSkillEffectTimer(MOVING_ACCELERATION);
			}
			if (pc.hasSkillEffect(WIND_WALK)) { // 風之疾走 移速1.33倍
				pc.killSkillEffectTimer(WIND_WALK);
			}
			if (pc.hasSkillEffect(BLOODLUST)) { // 血之渴望 攻速1.33倍
				pc.killSkillEffectTimer(BLOODLUST);
			}
			if (pc.hasSkillEffect(STATUS_BRAVE2)) { // 超級加速 2.66倍
				pc.killSkillEffectTimer(STATUS_BRAVE2);
			}
			pc.setBraveSpeed(4);
			pc.sendPackets(new S_SkillBrave(pc.getId(), 4, time));
			pc.broadcastPacket(new S_SkillBrave(pc.getId(), 4, 0));
			break;
		case 102: case 104:
			time = 320;
			break;
		case 105:
			type = 1;
			typeNum = 12;
			time = 192;
			break;
		case 106:
			time = 192;
			pc.addDodge((byte) 5); // 閃避率 + 50%
			// 更新閃避率顯示
			break;
		case 109:
			time = 960;
			pc.addStr((byte) 2);
			pc.sendPackets(new S_Strup(pc, 2, time));
			break;
		case 110:
			time = 960;
			pc.addDex((byte) 2);
			pc.sendPackets(new S_Dexup(pc, 2, time));
			break;
		case 111:
			time = 32;
			break;
		case 114:
			time = 640;
			pc.addHitup(5);
			pc.addBowHitup(5);
			pc.addMr(20);
			pc.sendPackets(new S_SPMR(pc));
			pc.sendPackets(new S_SkillIconAura(113, time));
			break;
		case 115:
			time = 640;
			pc.addAc(-8);
			pc.sendPackets(new S_SkillIconAura(114, time));
			break;
		case 117:
			time = 640;
			pc.addDmgup(5);
			pc.sendPackets(new S_SkillIconAura(116, time));
			break;
		case 129:
			time = 1200;
			pc.addMr(10);
			pc.sendPackets(new S_SPMR(pc));
			break;
		case 137:
			time = 1200;
			pc.addWis((byte) 3);
			pc.resetBaseMr();
			break;
		case 138:
			time = 1200;
			pc.addWind(10);
			pc.addWater(10);
			pc.addFire(10);
			pc.addEarth(10);
			pc.sendPackets(new S_OwnCharAttrDef(pc));
			break;
		case 147:
			time = 64;
			int attr = pc.getElfAttr();
			if (attr == 1) {
				pc.addEarth(50);
			} else if (attr == 2) {
				pc.addFire(50);
			} else if (attr == 4) {
				pc.addWater(50);
			} else if (attr == 8) {
				pc.addWind(50);
			}
			break;
		
		case 148:
			time = 960;
			pc.addDmgup(4);
			pc.sendPackets(new S_SkillIconAura(147, time));
			break;
		case 163:
			time = 960;
			pc.addDmgup(6);
			pc.addHitup(3);
			pc.sendPackets(new S_SkillIconAura(162, time));
			break;
		case 171:
			time = 192;
			break;
		case 175:
			time = 64;
			break;
		case 176:
			time = 960;
			break;
		case 149:
			time = 960;
			pc.addBowHitup(6);
			pc.sendPackets(new S_SkillIconAura(148, time));
			break;
		case 150:
			time = 960;
			pc.setBraveSpeed(4);
			pc.sendPackets(new S_SkillBrave(pc.getId(), 4, time));
			pc.broadcastPacket(new S_SkillBrave(pc.getId(), 4, 0));
			break;
		case 166:
			time = 960;
			pc.addBowDmgup(5);
			pc.addBowHitup(-1);
			pc.sendPackets(new S_SkillIconAura(165, time));
			break;
		case 151:
			time = 960;
			pc.addAc(-6);
			pc.sendPackets(new S_SkillIconShield(6, time));
			break;
		case 168:
			time = 960;
			pc.addAc(-10);
			pc.sendPackets(new S_SkillIconShield(10, time));
			break;
		case 169:
			time = 960;
			break;
		case 158:
			time = 320;
			break;
		case 160:
			time = 960;
			break;
		
		case 170:
			time = 64;
			break;
		case 181:
			time = 1800;
			break;
		case 186:
			time = 300;
			pc.setBraveSpeed(1);
			pc.sendPackets(new S_SkillBrave(pc.getId(), 1, time));
			pc.broadcastPacket(new S_SkillBrave(pc.getId(), 1, 0));
			break;
		case 191:
			time = 300;
			break;
		case 201:
			time = 1200;
			pc.addDodge((byte) 5); // 閃避率 + 50%
			break;
		case 204://
			time = 32;
			pc.addDmgup(4);
			pc.addHitup(4);
			pc.addBowDmgup(4);
			pc.addBowHitup(4);
			break;
		case 206://
			time = 300;
			pc.addMpr(2);
			break;
		case 209://
			time = 32;
			pc.addSp(2);
			break;
		case 211:
			time = 600;			
			break;
		case 216://
			time = 300;
			pc.addStr((byte) 1);
			pc.addCon((byte) 1);
			pc.addDex((byte) 1);
			pc.addWis((byte) 1);
			pc.addInt((byte) 1);
			break;
		case 219:
			time = 32;
			pc.addDmgup(10);
			pc.addBowDmgup(10);
			break;
		case 214:
			time = 32;
			pc.addAc(-20);
			break;			
		}
		
		if (skillid == 90 || skillid == 91 || skillid == 105 || skillid == 106 || skillid == 201 || skillid == 171){
			checkEquipped = checkEquippedItem(skillid, pc, type, typeNum);
		}
		
		if (checkEquipped){
			pc.setSkillEffect(skillid, time * 1000);
			pc.sendPackets(new S_PacketBox(88, pc.getDodge()));
			pc.broadcastPacket(new S_SkillSound(pc.getId(), img));
			pc.sendPackets(new S_SkillSound(pc.getId(), img));
			pc.turnOnOffLight();
			pc.sendPackets(new S_OwnCharAttrDef(pc));
			pc.sendPackets(new S_OwnCharStatus(pc));
		} else {
			BuffDoll_DollSkill_Table updateSkill = BuffDoll_DollSkill_Table.getInstance();
			updateSkill.loadDollSkill_Info(itemid);
			BuffDoll_DollSkill_Load Skill = BuffDoll_DollSkill_Table.getInstance().getTemplate(itemid);	
			BuffDoll_Info_Load infonow = BuffDoll_Info_Table.getInstance().getTemplate(itemid);
			BuffDoll_Info_Table updateinfo = BuffDoll_Info_Table.getInstance();
			
			String[] htmldata;
			String htmlid = "";
			String status = "啟動";
			String heal = String.valueOf(pc.getHierarch() * 10);
			endSkill(place, infonow, Skill);
			updateSkill.UpdateDollSkill_Info(itemid, Skill);
			updateinfo.updateBuffDoll_info(itemid, infonow);
			
			htmldata = infonow.getInfo(name, mp, maxMp, status, heal);
			htmlid = "BuffD_FP";
			pc.sendPackets(new S_NPCTalkReturn(getid, htmlid, htmldata));
		}
	}
	
	private static boolean deleteRepeatedSkills(L1PcInstance pc, int skillId) {
		boolean isTrue = true;
		final int[][] repeatedSkills =
		{
				// 火焰武器、風之神射、烈炎氣息、暴風之眼、烈炎武器、暴風神射、媽祖的祝福
				{ FIRE_WEAPON, WIND_SHOT, FIRE_BLESS, STORM_EYE, BURNING_WEAPON, STORM_SHOT, EFFECT_BLESS_OF_MAZU },
				// 防護罩、影之防護、大地防護、大地的祝福、鋼鐵防護
				{ SHIELD, SHADOW_ARMOR, EARTH_SKIN, EARTH_BLESS, IRON_SKIN },
				// 勇敢藥水、精靈餅乾、(神聖疾走、行走加速、風之疾走)、超級加速、血之渴望
				{ STATUS_BRAVE, STATUS_ELFBRAVE, HOLY_WALK, MOVING_ACCELERATION, WIND_WALK, STATUS_BRAVE2, BLOODLUST },
				// 加速術、強力加速術、自我加速藥水
				{ HASTE, GREATER_HASTE, STATUS_HASTE },
				// 緩速、集體緩術、地面障礙
				{ SLOW , MASS_SLOW , ENTANGLE },
				// 通暢氣脈術、敏捷提升
				{ PHYSICAL_ENCHANT_DEX, DRESS_DEXTERITY },
				// 體魄強健術、力量提升
				{ PHYSICAL_ENCHANT_STR, DRESS_MIGHTY },
				// 激勵士氣、鋼鐵士氣
				{ GLOWING_AURA, SHINING_AURA },
				// 鏡像、暗影閃避
				{ 201, 106 },
				// 雙重破壞、屬性之火
				{ 105, 171 },
				// 反擊屏障、致命身軀
				{ 91, 191}
		};

		for (int[] skills : repeatedSkills) {
			for (int id : skills) {
				if (id == skillId) {
					stopSkillList(pc, skillId, skills);
					isTrue = false;
				}
			}
		}
		return isTrue;
	}

	// 將重複的狀態刪除
	private static void stopSkillList(L1PcInstance pc, int _skillId, int[] repeat_skill) {
		for (int skillId : repeat_skill) {
			if (skillId != _skillId) {
				pc.removeSkillEffect(skillId);
			}
		}
	}
	
	private static boolean checkEquippedItem(int skillid, L1PcInstance pc, int type, int typenum){
		int i  = pc.getInventory().getTypeEquipped(type, typenum);
		boolean isTrue = true;
		switch (skillid){
		case 90:
			if (i != 1){
				pc.sendPackets(new S_SystemMessage("必需裝備盾牌才能使用此技能"));
				isTrue = false;
			}
			break;
		case 91:
			if (i != 1){
				pc.sendPackets(new S_SystemMessage("必需裝備雙手劍才能使用此技能"));
				isTrue = false;
			}
			break;
		case 105:
			int k = pc.getInventory().getTypeEquipped(type,  11);
			if (i != 1 || k != 1){
				pc.sendPackets(new S_SystemMessage("必需裝備雙刀或鋼爪才能使用此技能"));
				isTrue = false;
			}
			break;
		case 171:
			if (pc.getClassId() == 2786 || pc.getClassId() == 2796){
				pc.sendPackets(new S_SystemMessage("你的職業不能使用此技能"));
				isTrue = false;
			}
			break;
		case 106:
			if (pc.getClassId() == 6671 || pc.getClassId() == 6650){
				pc.sendPackets(new S_SystemMessage("你的職業不能使用此技能"));
				isTrue = false;
			}
			break;
		case 201:
			if (pc.getClassId() == 2786 || pc.getClassId() == 2796){
				pc.sendPackets(new S_SystemMessage("你的職業不能使用此技能"));
				isTrue = false;
			}
			break;
		}
		return isTrue;
	}
	
	private void endSkill(int i, BuffDoll_Info_Load info,BuffDoll_DollSkill_Load skill){
		switch (i)
		{
		case 1:
			info.setPlace1Use(false);
			skill.setResident(false, i);
			break;
		case 2:
			info.setPlace2Use(false);
			skill.setResident(false, i);
			break;
		case 3:
			info.setPlace3Use(false);
			skill.setResident(false, i);
			break;
		case 4:
			info.setPlace4Use(false);
			skill.setResident(false, i);
			break;
		case 5:
			info.setPlace5Use(false);
			skill.setResident(false, i);
			break;
		case 6:
			info.setPlace6Use(false);
			skill.setResident(false, i);
		break;
		}
	}
}
